﻿using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.IO;

#if UNITY_EDITOR
using Sirenix.OdinInspector;
#endif

namespace IQIGame.Onigao.Framework
{
    using UDebug = UnityEngine.Debug;

    /// <summary>
    /// 类名 : 自定义数字对应美术图片序列化数据
    /// 作者 : Canyon / 龚阳辉
    /// 日期 : 2024-06-25 16:33
    /// 功能 : 
    /// </summary>
    [CreateAssetMenu(fileName = "NewArtNumSpriteAsset", menuName = "Tools/CreateArtNumSpriteAsset", order = int.MinValue)]
    public class ArtSpriteNumAsset : ScriptableObject
    {
        public ArtArtNumSpriteData[] datas = new ArtArtNumSpriteData[0];
        private Dictionary<int, ArtArtNumSpriteData> dic;

        private void OnEnable()
        {
            this.InitDic();
        }

        private Dictionary<int, ArtArtNumSpriteData> InitDic(bool isImmediate = false)
        {
            if (this.dic != null && !isImmediate)
                return this.dic;

            if (this.dic == null)
                this.dic = new();
            this.dic.Clear();

            if (this.datas == null || this.datas.Length == 0)
                return this.dic;

            foreach (var data in this.datas)
            {
                if (this.dic.ContainsKey(data.key))
                    UDebug.LogErrorFormat("====== same key =[{0}] , curr = [{1}] , last = [{2}]", data.key, data.sprite, this.dic[data.key].sprite);
                else
                    this.dic.Add(data.key, data);
            }
            return this.dic;
        }

        public ArtArtNumSpriteData GetData(int key)
        {
            var dic = this.InitDic();
            if (dic.TryGetValue(key, out ArtArtNumSpriteData data))
                return data;
            return null;
        }

        public Sprite this[int key]
        {
            get
            {
                var data = this.GetData(key);
                if (data == null) return null;
                return data.sprite;
            }
        }

#if UNITY_EDITOR
        [Button, ButtonGroup("Editor")]
        private void FindSelf()
        {
            EditorGUIUtility.PingObject(this);
            Selection.activeObject = this;
        }

        [Button, ButtonGroup("Editor"), GUIColor(1, 0.3f, 0)]
        private void ClearDatas()
        {
            this.datas = new ArtArtNumSpriteData[0];
        }

        [Button(ButtonSizes.Medium), ButtonGroup("Editor"), GUIColor(0, 1, 0)]
        private void SaveDatas()
        {
            AssetDatabase.SaveAssetIfDirty(this);
            AssetDatabase.Refresh();
        }

        [FoldoutGroup("AutoImportNumSprite", false), ShowInInspector]
        private string assetPathFormat = "Assets/Res/05_Images/Sprite/UIHero/HeroInfo_LvNum_{0}.png";

        [FoldoutGroup("AutoImportNumSprite", false), ShowInInspector, ShowIf("@!string.IsNullOrEmpty(this.assetPathFormat)")]
        private int numStart = 0;

        [FoldoutGroup("AutoImportNumSprite", false), ShowInInspector, ShowIf("@!string.IsNullOrEmpty(this.assetPathFormat)")]
        private int numEnd = 9;

        [FoldoutGroup("AutoImportNumSprite", false), Button(ButtonSizes.Large), GUIColor(0, 1, 0), ShowIf("@this.numStart <= this.numEnd && !string.IsNullOrEmpty(this.assetPathFormat)")]
        private void AutoImportNumSprite()
        {
            int diff = this.numEnd - this.numStart + 1;
            this.datas = new ArtArtNumSpriteData[diff];

            int iKey = 0;
            for (int i = 0; i < diff; i++)
            {
                iKey = i + this.numStart;
                var assetPath = string.Format(assetPathFormat, iKey);
                this.datas[i] = new ArtArtNumSpriteData()
                {
                    key = iKey,
                    sprite = AssetDatabase.LoadAssetAtPath<Sprite>(assetPath),
                };
            }

            this.SaveDatas();
        }
#endif
    }

    [Serializable]
    public class ArtArtNumSpriteData
    {
        public int key;
#if UNITY_EDITOR
        [InlineEditor(InlineEditorModes.LargePreview)]
#endif
        public Sprite sprite;
    }

#if UNITY_EDITOR
    public static class ArtNumSpriteAssetHelper
    {
        [MenuItem("Assets/Create/Tools/CreateArtNumSpriteAssetBySelection", false, int.MinValue)]
        static private void CreateArtNumSpriteAssetBySelection()
        {
            var uobjs = Selection.objects;
            Dictionary<string, List<Texture2D>> dicName2List = new(4);
            string prefix = string.Empty;
            foreach (var uobj in uobjs)
            {
                if (uobj is Texture2D txt2d)
                {
                    prefix = txt2d.name.Substring(0, txt2d.name.LastIndexOf("_"));
                    if (!dicName2List.TryGetValue(prefix, out var list2D))
                    {
                        list2D = new(4);
                        dicName2List.Add(prefix, list2D);
                    }
                    list2D.Add(txt2d);
                }
                // Debug.LogError($"{uobj.GetType().Name} = {uobj.GetType()}");
            }
            List<Texture2D> listMaxCount = null;
            if (dicName2List.TryGetValue(prefix, out listMaxCount))
            {
                foreach (var kv in dicName2List)
                {
                    if (kv.Value == listMaxCount)
                        continue;
                    if (listMaxCount.Count < kv.Value.Count)
                    {
                        listMaxCount = kv.Value;
                        prefix = kv.Key;
                    }
                }
            }

            int cnt = listMaxCount?.Count ?? 0;
            if (cnt == 0)
            {
                return;
            }

            ArtArtNumSpriteData[] datas = new ArtArtNumSpriteData[cnt];

            Texture2D texture2D = null;
            string strNum = string.Empty;
            int iKey = 0;
            string assetPath = string.Empty;
            for (int i = 0; i < cnt; i++)
            {
                texture2D = listMaxCount[i];
                strNum = texture2D.name.Substring(texture2D.name.LastIndexOf("_"));
                while (strNum.StartsWith("_") || strNum.StartsWith("0"))
                {
                    strNum = strNum.Substring(1);
                }

                if (string.IsNullOrEmpty(strNum))
                {
                    strNum = "0";
                }

                if (!int.TryParse(strNum, out iKey))
                {
                    Debug.LogError($"Error2Num, {strNum} = {texture2D.name}");
                    continue;
                }
                assetPath = AssetDatabase.GetAssetPath(texture2D);
                datas[i] = new ArtArtNumSpriteData()
                {
                    key = iKey,
                    sprite = AssetDatabase.LoadAssetAtPath<Sprite>(assetPath),
                };
            }
            string pathNoAsset = Application.dataPath.Replace("Assets", "").Replace("\\", "/");
            string assetPathRoot = "Assets/Res/16_ScriptableConfig/ArtSpriteNumAsset";
            if (Directory.Exists(pathNoAsset + assetPathRoot))
            {
                assetPathRoot += "/";
            }
            else
            {
                texture2D = listMaxCount[0];
                assetPathRoot = AssetDatabase.GetAssetPath(texture2D);
                assetPathRoot = assetPathRoot.Substring(0, assetPathRoot.LastIndexOf(texture2D.name));
            }
            assetPath = $"{assetPathRoot}{prefix}.asset";
            ArtSpriteNumAsset asset = ScriptableObject.CreateInstance<ArtSpriteNumAsset>();
            asset.datas = datas;
            if (File.Exists(assetPath))
            {
                File.Delete(assetPath);
            }
            AssetDatabase.CreateAsset(asset, assetPath);
            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();
        }
    }
#endif

}
